package com.yoke.ip;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoke.system.log.SystemLog;
import com.yoke.util.StringUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.DocumentException;

import java.io.IOException;
import java.util.HashMap;

/**
 * Created by jiangzeyin on 2017/2/21.
 */
public class IpUtil {
    private static final int CaCheSize = 10000;
    private static final HashMap<String, HashMap<String, Boolean>> ID_HASH_MAP = new HashMap<>();

    public static void remove(String id) {
        ID_HASH_MAP.remove(id);
    }

    public static int getCaCheSize(String id) {
        HashMap<String, Boolean> hashMap = ID_HASH_MAP.get(id);
        if (hashMap == null)
            return 0;
        return hashMap.size();
    }

    /**
     * 清理 ip 缓存
     *
     * @param id id
     */
    public static void clearCache(String id) {
        HashMap<String, Boolean> hashMap = ID_HASH_MAP.get(id);
        if (hashMap != null) {
            int count = hashMap.size();
            if (count > 0) {
                hashMap.clear();
                SystemLog.LOG().info(id + " 清空缓存数量：" + count);
            }
        }
    }

    public static boolean isCan(String ip, JSONObject item, boolean mod) throws IOException, DocumentException, RuntimeException {
        String id = item.getString("id");
        HashMap<String, Boolean> hashMap = ID_HASH_MAP.computeIfAbsent(id, k -> new HashMap<>(CaCheSize));
        Boolean bool = hashMap.get(ip);
        if (bool != null)
            return bool;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String url = String.format("http://ip.taobao.com//service/getIpInfo.php?ip=%s", ip);
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpClient.execute(httpGet);
        String resString = EntityUtils.toString(response.getEntity());
        JSONObject jsonObject = JSONObject.parseObject(resString);
        Integer code = jsonObject.getInteger("code");
        if (code == null) {
            SystemLog.LOG().info("ip:" + ip + " taobao 接口获取失败");
            return sina(ip, item, mod);
        }
        if (code != 0) {
            SystemLog.LOG().info("ip:" + ip + " taobao 接口" + resString);
            return sina(ip, item, mod);
        }
        JSONObject data = jsonObject.getJSONObject("data");
        if (data == null) {
            SystemLog.LOG().info("ip:" + ip + " taobao 接口json 为空");
            return sina(ip, item, mod);
        }
        JSONArray region = item.getJSONArray("region");
        String regionInfo = data.getString("region");
        boolean flag = check(regionInfo, region, mod);
        if (flag) {
            JSONArray city = item.getJSONArray("city");
            String cityInfo = data.getString("city");
            flag = check(cityInfo, city, mod);
        }
        if (hashMap.size() == CaCheSize) {
            hashMap.clear();
            SystemLog.LOG().info(id + "缓存数量达到上限");
        }
        hashMap.put(ip, flag);
        return flag;
    }

    private static boolean check(String str, JSONArray jsonArray, boolean mod) {
        if (jsonArray == null)
            return true;
        for (Object o : jsonArray) {
            String item = (String) o;
            if ("全部".equals(item))
                return false;
            if ("手机".equals(item) && mod)
                return false;
            if ("电脑".equals(item) && !mod)
                return false;
            if (str.contains(item))
                return false;
            item = item.replace("省", "").replace("市", "");
            if (str.contains(item))
                return false;
        }
        return true;
    }

    private static boolean sina(String ip, JSONObject item, boolean mod) throws IOException {
        String id = item.getString("id");
        HashMap<String, Boolean> hashMap = ID_HASH_MAP.computeIfAbsent(id, k -> new HashMap<>(CaCheSize));
        Boolean bool = hashMap.get(id);
        if (bool != null)
            return bool;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String url = String.format("http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=%s", ip);
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpClient.execute(httpGet);
        String resString = EntityUtils.toString(response.getEntity());
        JSONObject jsonObject;
        try {
            jsonObject = JSONObject.parseObject(resString);
        } catch (Exception e) {
            SystemLog.ERROR().error("解析ip 地址失败", e);
            SystemLog.LOG().info("新浪ip:" + ip + "  json:" + resString);
            return false;
        }
        //  判断省份
        String province = StringUtil.convertNULL(jsonObject.getString("province"));
        boolean flag = check(province, item.getJSONArray("region"), mod);
        if (flag) {
            // 判断城市
            JSONArray city = item.getJSONArray("city");
            String cityInfo = StringUtil.convertNULL(jsonObject.getString("city"));
            flag = check(cityInfo, city, mod);
        }
        if (hashMap.size() == CaCheSize) {
            hashMap.clear();
            SystemLog.LOG().info(id + "缓存数量达到上限");
        }
        hashMap.put(ip, flag);
        return flag;
    }
}
